<?php

namespace App\Http\Controllers;

use App\Address;
use App\Exceptions\Interfaces\AddressServiceException;
use App\Exceptions\Interfaces\OrderServiceException;
use App\Interfaces\AddressService;
use App\Interfaces\CouponService;
use App\Interfaces\OrderService;
use App\OrderPay;
use App\Policies\OrderPayPolicy;
use App\User;
use App\UserCoupon;
use EasyWeChat\Kernel\Exceptions\HttpException;
use Illuminate\Http\Request;
use Yansongda\Pay\Log;

class OrderController extends Controller
{

    public function index($orderId, Request $request, OrderService $orderService, AddressService $addressService, CouponService $couponService)
    {

        $order = $orderService->OrderDetail($orderId);


        if (!isset($order->address)) {
            //取出用户默认地址
            $address = $addressService->getUserDefaultAddress(\Auth::id());
        }

        $myCoupon = $couponService->getUserCoupon(\Auth::id(), ['type_status' => 1]);//未使用的优惠券


        if ($order->paid_at || $order->closed) {
            return view('mobile.order.closed', compact('order', 'address'));
        }
        try {
            $jsSdk = \EasyWeChat::officialAccount()
                ->jssdk
                ->buildConfig(['chooseWXPay'], false, false, true);

        } catch (HttpException $exception) {
            return $exception->getMessage();
            $jsSdk = json_encode();
        }
        return view('mobile.order.index', compact('order', 'jsSdk', 'address', 'myCoupon'));
    }

    public function payfor(Request $request, OrderService $orderService, AddressService $addressService)
    {//支付

        $pay_type = $request->pay_type;
        $is_balance = $request->is_banlance;

        $return = ['message' => '', 'code' => 0];
        if (!$pay_type && !$is_balance) {
            $return['message'] = '请选择一种支付方式';
            return Response()->json($return);
        }
        $validator = \Validator::make($request->all(),
            [
                'order_id' => 'required',
                'address_id' => 'required',

            ],
            [
                'order_id.required' => '支付订单不能为空',
                'address_id.required' => '请选择一个地址',

            ]);
        if ($validator->fails()) {
            $error = $validator->errors();
            foreach ($error->all() as $message) {
                $return['message'] = $message;
                return Response()->json($return);
            }
        }
        //绑定地址
        $orderPay = OrderPay::find($request->order_id);
        if (!$orderPay) {
            return Response()->json(
                [
                    'code' => 0,
                    'message' => '订单不存在'
                ]
            );
        }
        if($orderPay->closed==1){
            return Response()->json(
                [
                    'code' => 0,
                    'message' => '订单已取消'
                ]
            );
        }

        if ($orderPay->paid_at) {
            return Response()->json(
                [
                    'code' => 0,
                    'message' => '订单已支付'
                ]
            );
        }
        $address = $addressService->getAddress($request->address_id);

        $address = $orderService->bindAddress($address, $orderPay);
        //绑定优惠券

        $orderPay = $orderService->bindCouPon($request->user_coupon_id, $orderPay);

       // dd($orderPay);
        if ($orderPay->pay_price == 0) {
            //当金额为零时 直接支付处理
            $orderService->OrderHanle($orderPay);
            return Response()->json(['message' => '支付成功', 'code' => 1]);
        }

        if ($is_balance && !$pay_type) {
            return $this->moneyPay($orderPay, $orderService);
        }

        if ($pay_type) {
            if($is_balance){
                if ($orderPay->pay_price < \Auth::user()->money) {//如果用户零钱大于付款金额 直接零钱支付
                    return $this->moneyPay($orderPay, $orderService);
                }
                $orderPay = $this->bindMoney($orderPay);
            }

            switch ($request->pay_type) {
                case 3 :
                    return $this->wechatPay($orderPay, $orderService, $request);
                    break;
                case 2 :
                    return $this->alipay($orderPay, $orderService);
                    break;
                default :
                    return $this->moneyPay($orderPay, $orderService);
                    break;
            }
        }
    }

    protected function moneyPay(OrderPay $orderPay, $orderService)
    {//余额支付
        //查看用户余额
        $user = User::find(\Auth::id());
        if ($user->money < $orderPay->pay_price) {
            throw new AddressServiceException('余额不足');
        }
        //执行订单处理
        $orderService->OrderHanle($orderPay);
        //执行完用户建余额
        User::where('id', $user->id)->decrement('money', $orderPay->pay_price);
        $orderPay->pay_type = OrderPay::PAY_BALANCE;
        $orderPay->subject = '购买商品';
        $orderPay->save();
        return Response()->json(['message' => '支付成功', 'code' => 1]);

    }

    protected function wechatPay(OrderPay $orderPay, $orderService, $request)
    {//微信支付
        //实例化微信支付
        $payment = \EasyWeChat::payment();
        $user = User::findOrFail(\Auth::id());
        $jssdk = $payment->jssdk;
        $total_fee = ($orderPay->pay_price - $orderPay->pay_balance) * 100;
        $total_fee = (int)round($total_fee);
        $result = $payment->order->unify([
            'body' => '商品支付',
            'out_trade_no' => $orderPay->pay_sn,
            'total_fee' => $total_fee,
            'trade_type' => 'JSAPI',
            'openid' => \Auth::user()->openid,
        ]);
        if ($result['return_code'] == 'FAIL') {
            throw new OrderServiceException($result['return_msg']);
        }
        $orderPay->pay_type = OrderPay::PAY_WECHAT;
        $orderPay->save();
        //todo 普通手机浏览器 H5支付
        $config = $jssdk->bridgeConfig($result['prepay_id'], false);
        return Response()->json(['message' => $config, 'code' => 2]);
    }

    protected function bindMoney(OrderPay $orderPay)
    {
        $user = User::find(\Auth::id());
        \DB::transaction(function()use($user,$orderPay){
                if($orderPay->pay_balance==0){
                    $payBalance=$orderPay->pay_price>$user->money ? $user->money : $orderPay->pay_price;
                    $orderPay->pay_balance = $payBalance;
                    $orderPay->save();
                    User::where('id',$user->id)->decrement('money',$payBalance);
                }
        });
        return $orderPay;
    }

    /**
     * @param OrderPay $orderPay
     * @param $orderService
     * @return mixed
     */
    protected function alipay(OrderPay $orderPay, $orderService)
    {//阿里云支付
        $orderPay->pay_type = OrderPay::PAY_ALI;
        $orderPay->save();
        return Response()->json(['message' => '前往支付宝支付', 'code' => 1]);
    }

    /**
     * @param Request $request
     * 阿里云web支付
     */
    public function alipayWeb(Request $request)
    {

        $orderPayId = $request->orderPayId;
        if (!$orderPayId) {
            abort('404', '参数错误');
        }
        $orderPay = OrderPay::find($orderPayId);
        if ($orderPay->closed == true) {
            throw  new OrderServiceException('订单已关闭');
        }
        if($orderPay->pay_status==1){//判断支付
            return redirect()->route('order.success',['order'=>$orderPay->order_pay_id]);
        }
        // 判断是否是微信
        if (is_weixin()) {
            return view('mobile.wechat.alipay');
        }
        return app('alipay')->web(
            [
                'out_trade_no' => $orderPay->pay_sn,
                'total_amount' => $orderPay->pay_price - $orderPay->pay_balance,
                'subject' => '商品订单支付',
            ]
        );

    }

    //支付回调通知
    public function wechatNotify(OrderService $orderService)
    {
        $app = \EasyWeChat::payment();
        $response = $app->handlePaidNotify(function ($message, $fail) use ($orderService) {
            // 你的逻辑
            $orderPay = OrderPay::where('pay_sn', $message['out_trade_no'])->first();
            $orderService->OrderHanle($orderPay);
            return true;
            // 或者错误消息
            $fail('Order not exists.');
        });
        return $response;
    }

    public function alipayNotify(OrderService $orderService)
    {
        $alipay = app('alipay');

        try {
            $data = $alipay->verify(); // 是的，验签就这么简单！

            // 请自行对 trade_status 进行判断及其它逻辑进行判断，在支付宝的业务通知中，只有交易通知状态为 TRADE_SUCCESS 或 TRADE_FINISHED 时，支付宝才会认定为买家付款成功。
            // 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号；
            // 2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额）；
            // 3、校验通知中的seller_id（或者seller_email) 是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email）；
            // 4、验证app_id是否为该商户本身。
            // 5、其它业务逻辑情况
            $orderPay = OrderPay::where('pay_sn', $data['out_trade_no'])->first();
            $orderService->OrderHanle($orderPay);
            Log::debug('Alipay notify', $data->all());
        } catch (Exception $e) {
            $e->getMessage();
        }

        return $alipay->success();
    }

}
